package com.yami.shop.im.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.yami.shop.bean.model.ShopDetail;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.Json;
import com.yami.shop.im.bo.ShopSessionInfo;
import com.yami.shop.im.bo.SysSessionInfo;
import com.yami.shop.im.bo.UserSessionInfo;
import com.yami.shop.im.param.SysUserParam;
import com.yami.shop.im.socket.PlatformWebSocketServer;
import com.yami.shop.im.socket.UserWebSocketServer;
import com.yami.shop.im.vo.Conversation;
import com.yami.shop.im.vo.MsgItem;
import com.yami.shop.service.ShopDetailService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.im.dao.ImRecordMapper;
import com.yami.shop.im.bean.ImRecord;
import com.yami.shop.im.service.ImRecordService;
import org.springframework.transaction.annotation.Transactional;

@Service
@AllArgsConstructor
public class ImRecordServiceImpl extends ServiceImpl<ImRecordMapper, ImRecord> implements ImRecordService{

    private final ImRecordMapper imRecordMapper;

    private ShopDetailService shopDetailService;

    @Override
    public List<ImRecord> listHistory(Long shopId, String userId, Integer size, Integer sendType) {
        return imRecordMapper.listHistory(shopId, userId, size,sendType);
    }

    @Override
    public List<Conversation> listConversationByUserId(String userId, Integer maxDay) {
        List<Conversation> conversations = imRecordMapper.listConversationByUserId(userId, maxDay);
        if (CollectionUtil.isEmpty(conversations)) {
            return new ArrayList<>();
        }
        for (Conversation conversation : conversations) {
            Date latestMsgTime = conversation.getLatestMsgTime();
            conversation.setTimestamp(latestMsgTime.getTime());
//            if (DateUtil.isSameDay(latestMsgTime, new Date())) {
//                conversation.setTimeStr(DateUtil.format(latestMsgTime, "HH:mm"));
//            } else {
//
//            }
            conversation.setTimeStr(DateUtil.format(latestMsgTime, "yyyy/MM/dd"));
            ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(conversation.getShopId());
            if (shopDetail != null && shopDetail.getShopStatus() != null) {
                conversation.setShopStatus(shopDetail.getShopStatus());
            }
        }

        return conversations;
    }

    @Override
    public List<Conversation> listConversationByShopId(Long shopId, Integer maxDay, int sendType) {
        List<Conversation> conversations = imRecordMapper.listConversationByShopId(shopId, maxDay,sendType);
        if (CollectionUtil.isEmpty(conversations)) {
            return new ArrayList<>();
        }
        for (Conversation conversation : conversations) {
            Date latestMsgTime = conversation.getLatestMsgTime();
            conversation.setTimestamp(latestMsgTime.getTime());
//            if (DateUtil.isSameDay(latestMsgTime, new Date())) {
//                conversation.setTimeStr(DateUtil.format(latestMsgTime, "HH:mm"));
//            } else {
//
//            }
            conversation.setTimeStr(DateUtil.format(latestMsgTime, "yyyy/MM/dd HH:mm"));
        }

        return conversations;
    }

    @Override
    public void updateToRead(String userId, Long shopId, int source, int sendType) {
        imRecordMapper.updateToRead(userId, shopId, source,sendType);
    }

    @Override
    public MsgItem getMsgItem(ShopSessionInfo shopSessionInfo, UserSessionInfo userSessionInfo, ImRecord record) {
        MsgItem msgItem = new MsgItem();
        msgItem.setUserId(userSessionInfo.getUserId());
        msgItem.setUserHeadUrl(userSessionInfo.getPic());
        msgItem.setUserName(userSessionInfo.getNickName());
        msgItem.setShopLogo(shopSessionInfo.getPic());
        msgItem.setShopId(shopSessionInfo.getShopId());
        msgItem.setShopName(shopSessionInfo.getShopName());
        msgItem.setTimestamp(record.getCreateTime().getTime());
        msgItem.setTimeStr(DateUtil.format(record.getCreateTime(), "yyyy/MM/dd HH:mm"));
        msgItem.setContent(record.getContent());
        msgItem.setType(record.getType());
        msgItem.setSource(record.getSource());
        msgItem.setItemId(record.getId());
        return msgItem;
    }

    @Override
    public MsgItem getMsgItemByPlatform(SysSessionInfo sysSessionInfo, UserSessionInfo userSessionInfo, ImRecord record) {
        MsgItem msgItem = new MsgItem();
        msgItem.setUserId(userSessionInfo.getUserId());
        msgItem.setUserHeadUrl(userSessionInfo.getPic());
        msgItem.setUserName(userSessionInfo.getNickName());
        msgItem.setShopId(sysSessionInfo.getUserId());
        msgItem.setShopName(sysSessionInfo.getUserName());
        msgItem.setTimestamp(record.getCreateTime().getTime());
        msgItem.setTimeStr(DateUtil.format(record.getCreateTime(), "yyyy/MM/dd HH:mm"));
        msgItem.setContent(record.getContent());
        msgItem.setType(record.getType());
        msgItem.setSource(record.getSource());
        msgItem.setItemId(record.getId());
        msgItem.setMassMsgCode(record.getMassMsgCode());
        return msgItem;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void receiveMsg(Long id, Long userId) throws IOException{
        ImRecord imRecord = getOne(new LambdaQueryWrapper<ImRecord>().eq(ImRecord::getBizId, userId)
                .eq(ImRecord::getId,id));
        if(Objects.isNull(imRecord)){
            throw new YamiShopBindException("已被其他客服接收此消息！");
        }
        imRecord.setIsRead(1);
        updateById(imRecord);
        remove(new LambdaQueryWrapper<ImRecord>().eq(ImRecord::getMassMsgCode,imRecord.getMassMsgCode()));
        // 如果原来就有token
        UserSessionInfo userSessionInfo = UserWebSocketServer.USER_MAP.get(imRecord.getUserId());
        if(Objects.isNull(userSessionInfo)){
            throw new YamiShopBindException("yami.customer.no.online");
        }
        SysSessionInfo sysSessionInfo = PlatformWebSocketServer.SYS_MAP.get(userId);
        ImRecord sysRecord = new ImRecord();
        sysRecord.setSendType(1);
        sysRecord.setType(0);
        sysRecord.setIsRead(1);
        sysRecord.setSource(2);
        sysRecord.setBizId(userId);
        sysRecord.setUserId(imRecord.getUserId());
        sysRecord.setCreateTime(new Date());
        sysRecord.setContent("平台客服"+ sysSessionInfo.getUserName() +"已经接入。");
        save(sysRecord);
        // 将当前客服消息发给用户
        // 3.推送消息给前端
        MsgItem msgItem = getMsgItemByPlatform(sysSessionInfo, userSessionInfo, sysRecord);
        // 发给用户聊天记录
        userSessionInfo.getSession().getBasicRemote().sendText(Json.toJsonString(ServerResponseEntity.success(msgItem)));
    }

    @Override
    public SysUserParam getLatelyUser(int maxDay, String userId) {
        return imRecordMapper.getLatelyUser(maxDay,userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void forwardMsg(SysUserParam param) throws IOException {
        boolean isOnline = false;
        SysSessionInfo sysInfo = new SysSessionInfo();
        SysSessionInfo oriSysInfo = new SysSessionInfo();
        for (Long key : PlatformWebSocketServer.SYS_MAP.keySet()) {
            SysSessionInfo sysSessionInfo = PlatformWebSocketServer.SYS_MAP.get(key);
            // 对方在线则为true
            if (sysSessionInfo != null && Objects.equals(sysSessionInfo.getUserId(),param.getUserId())) {
                isOnline = true;
                sysInfo = sysSessionInfo;
            }
            if(sysSessionInfo != null && Objects.equals(sysSessionInfo.getUserId(),param.getOriUserId())){
                oriSysInfo = sysSessionInfo;
            }
        }
        // 如果原来就有token
        UserSessionInfo userSessionInfo = UserWebSocketServer.USER_MAP.get(param.getBizUserId());
        if(!isOnline || Objects.isNull(userSessionInfo)){
            throw new YamiShopBindException("yami.customer.no.online");
        }
        // 1.转发消息
        // 将当前客服消息修改转发给新的客服
        update(new LambdaUpdateWrapper<ImRecord>().set(ImRecord::getBizId,param.getUserId())
                .eq(ImRecord::getBizId,param.getOriUserId())
                .eq(ImRecord::getUserId,param.getBizUserId()));
        ImRecord imRecord = new ImRecord();
        imRecord.setSendType(1);
        imRecord.setType(0);
        imRecord.setIsRead(0);
        imRecord.setSource(2);
        imRecord.setBizId(param.getUserId());
        imRecord.setUserId(param.getBizUserId());
        imRecord.setCreateTime(new Date());
        imRecord.setContent("消息已经由"+ oriSysInfo.getUserName() +"转交给"+sysInfo.getUserName());
        imRecord.setForwardCode(1);
        save(imRecord);
        // 2.推送消息给对应客服
        MsgItem oriMsgItem = getMsgItemByPlatform(sysInfo, userSessionInfo, imRecord);
        oriMsgItem.setForwardCode(1);
        sysInfo.getSession().getBasicRemote().sendText(Json.toJsonString(ServerResponseEntity.success(oriMsgItem)));
        // 3.推送消息给前端
        MsgItem msgItem = getMsgItemByPlatform(sysInfo, userSessionInfo, imRecord);
        msgItem.setForwardCode(1);
        // 发给用户聊天记录
        userSessionInfo.getSession().getBasicRemote().sendText(Json.toJsonString(ServerResponseEntity.success(msgItem)));
    }
}
